package com.xmim.core.container;

import com.xmim.core.container.handler.AbstractHandlerManager;
import com.xmim.core.exception.ContainerException;

public abstract class AbstractServerContainer<N, H> extends AbstractHandlerManager<N, H> implements ServerContainer<N, H> {
    protected final ContainerFactory factory;
    protected final ServerContainer parent;
    protected boolean connect;
    private boolean isInit;

    public AbstractServerContainer(ContainerFactory factory, ServerContainer parent) {
        this.factory = factory;
        this.parent = parent;
    }

    @Override
    public AbstractServerContainer<N, H> addHandler(N type, H handler) {
        super.addHandler(type, handler);
        if (this.parent != null && this.parent.checkHandler(handler.getClass())) {
            this.parent.addHandler(type, handler);
        }
        return this;
    }


    @Override
    public AbstractServerContainer<N, H> start() throws ContainerException {
        if (this.parent != null && !this.parent.isConnect()) {
            this.parent.start();
        }
        if (!this.isInit) {
            this.isInit = true;
            this.onInit();
        }
        this.onBind();
        this.connect = true;
        return this;
    }


    @Override
    public AbstractServerContainer<N, H> close() throws ContainerException {
        if (this.parent != null) {
            this.parent.close();
        }
        this.onClose();
        this.connect = false;
        return this;
    }


    /**
     * 初始化
     */
    protected abstract void onInit() throws ContainerException;

    /**
     * 绑定服务并启动
     */
    protected abstract void onBind() throws ContainerException;

    /**
     * 关闭操作
     */
    protected abstract void onClose() throws ContainerException;


    @Override
    public boolean isConnect() {
        return connect;
    }

    @Override
    public Container getParent() {
        return parent;
    }

    @Override
    public ContainerFactory getFactory() {
        return factory;
    }

    public boolean isInit() {
        return isInit;
    }
}
